package com.tj.collection.controller.models;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.api.Page;
import com.fqgj.common.api.Response;
import com.fqgj.common.utils.CollectionUtils;
import com.fqgj.common.utils.DateUtil;
import com.fqgj.common.utils.HttpUtil;
import com.fqgj.common.utils.StringUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.jsoniter.output.JsonStream;
import com.kly.user.dto.*;
import com.kly.user.enums.ImageType;
import com.kly.user.enums.UserChatterMappingStatus;
import com.kly.user.enums.UserStatus;
import com.kly.user.service.ModelService;
import com.kly.user.service.UserService;
import com.tj.collection.aop.anno.LogEvent;
import com.tj.collection.bean.ApiResponse;
import com.tj.collection.common.RequestLocalInfo;
import com.tj.collection.common.Result;
import com.tj.collection.controller.BaseCompent;
import com.tj.collection.controller.chatter.request.ModelListRequest;
import com.tj.collection.controller.chatter.response.ChatterListResponse;
import com.tj.collection.controller.models.request.*;
import com.tj.collection.controller.models.response.AddImageRsp;
import com.tj.collection.controller.models.response.ModelsListResponse;
import com.tj.collection.db.domain.Admin;
import com.tj.collection.db.domain.Role;
import com.tj.collection.db.enums.RoleKeyEnum;
import com.tj.collection.db.service.AdminRoleService;
import com.tj.collection.db.service.AdminService;
import com.tj.collection.db.service.ChatterOptService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.io.File;
import java.util.*;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/models")
@Api(value = "modelController", tags = {"model相关页面处理接口"})
public class ModelController extends BaseCompent {

    private final Logger logger = LoggerFactory.getLogger(ModelController.class);

    @Resource
    private ModelService modelService;

    @Resource
    private UserService userService;

    @NacosValue(value = "${adminAccounts:tt}", autoRefreshed = true)
    private String adminAccounts;
    @NacosValue(value = "${user.photoPrefix}", autoRefreshed = true)
    private String userPhotoPrefix;
    @NacosValue(value = "${firebase.photoPrefix:https://firebasestorage.googleapis.com/v0/b/meboo-online-b68e7.appspot.com/o}", autoRefreshed = true)
    private String firebasePhotoPrefix;
    @NacosValue(value = "${meboo.url}", autoRefreshed = true)
    private String mebooApiUrl;
    @Resource
    AdminService adminService;
    @Resource
    ChatterOptService chatterOptService;

    @RequestMapping(value = "/list", method = {RequestMethod.POST})
    @ApiOperation("model列表接口")
    public Result<ModelsListResponse> modelsList(@RequestBody ModelListRequest request) {

        final BaseCompent.AccountRole accountRole = getAccountRole();

        Map<String, Object> params = setupQueryParams(request, accountRole);

        String serialize = JsonStream.serialize(params);

        List<Model> models = modelService.getModels(serialize, new Page(request.getPageSize(), request.getCurrent()));
        Map<String, String> modelLikeRateMap = getModelLikeRates(models);


        // 获取后台账号信息
        final List<Admin> admins = adminService.listAllAdmin();

        return Result.ok(new ModelsListResponse(models, adminAccounts.contains(RequestLocalInfo.getCurrentAdmin().getAccount()), userPhotoPrefix, admins, modelLikeRateMap).setTotalCnt(modelService.getModelsTotal(serialize)));
    }

    private Map<String, String> getModelLikeRates(List<Model> models) {
        if (CollectionUtils.isNotEmpty(models)) {
            final List<String> modelCodes = models.parallelStream().map(Model::getModelCode).collect(Collectors.toList());
            return chatterOptService.modelLikeRate(modelCodes);
        }
        return Maps.newHashMap();
    }

    private Map<String, Object> setupQueryParams(@RequestBody ModelListRequest request, BaseCompent.AccountRole accountRole) {
        Map<String, Object> params = new HashMap<>();
        if (StringUtils.isNotEmpty(request.getName())) {
            params.put("nickName", request.getName());
        }
        if (StringUtils.isNotEmpty(request.getModelCode())) {
            params.put("userCode", request.getModelCode());
        }
        if (StringUtils.isNotEmpty(request.getChatterCode())) {
            params.put("chatterCode", request.getChatterCode());
        }
        if (StringUtils.isNotEmpty(request.getChatterAccount())) {
            params.put("chatterAccount", request.getChatterAccount());
        }
        if (StringUtils.isNotEmpty(request.getChatterName())) {
            params.put("chatterName", request.getChatterName());
        }
        if (request.getAssignedChatter() != null && request.getAssignedChatter() != 99) {
            params.put("assignedChatter", request.getAssignedChatter());
        }
        if (request.getShowAllImages() != null) {
            params.put("showAllImages", request.getShowAllImages());
        }
        if (request.getApprovalStatus() != null && request.getApprovalStatus() != 99) {
            params.put("approvalStatus", request.getApprovalStatus());
        }
        if (request.getStatus() != null && request.getStatus() != 99) {
            params.put("status", request.getStatus());
        }
        if (request.getHasPrivateType() != null && request.getHasPrivateType() != 99) {
            params.put("hasPrivateType", request.getHasPrivateType());
        }

        if (request.getUserType() != null && request.getUserType() != 99) {
            params.put("userType", request.getUserType());
        }
        if (!accountRole.getHasViewAllDataPermission()) {
            params.put("chatterCodes", accountRole.getChatterCodes());
            params.put("createBy", RequestLocalInfo.getCurrentAdmin().getId());
        }
        return params;
    }

    @RequestMapping(value = "/detail", method = {RequestMethod.POST})
    @ApiOperation("model详细信息接口")
    public Result<ModelsListResponse> modelDetail(@RequestBody ModelCode request) {
        if (StringUtils.isEmpty(request.getModelCode())) {
            return Result.fail("modelCode should not be empty");
        }
        // 获取后台账号信息
        final List<Admin> admins = adminService.listAllAdmin();

        Model model = modelService.getModel(request.getModelCode());
        return Result.ok(new ModelsListResponse(Arrays.asList(model), true, userPhotoPrefix, admins, null));
    }

    @LogEvent(name = "updateModelStatus")
    @RequestMapping(value = "/updateAccountStatus", method = {RequestMethod.POST})
    @ApiOperation("禁、启用账号接口")
    public Result updateAccountStatus(@RequestBody ModelStauts modelStauts) {
        userService.updateUserStatus(modelStauts.getModelCode(), modelStauts.getStatus(), Integer.valueOf(String.valueOf(RequestLocalInfo.getCurrentAdmin().getId())));
        return Result.ok();
    }

    @LogEvent(name = "addModel")
    @RequestMapping(value = "/add", method = {RequestMethod.POST})
    @ApiOperation("model新增接口")
    public Result addModel(@RequestBody AddModel request) {
        AddModelDto modelDto = new AddModelDto();
        BeanUtils.copyProperties(request, modelDto);
        if (CollectionUtils.isEmpty(request.getPhotos())) {
            modelDto.setPhotos(request.getPhotos());
        }
        if (CollectionUtils.isEmpty(request.getPublicAlbum())) {
            modelDto.setPublicAlbum(request.getPublicAlbum());
        }
        if (CollectionUtils.isEmpty(request.getPrivateAlbum())) {
            modelDto.setPrivateAlbum(request.getPrivateAlbum());
        }

        Date date = DateUtil.getDate(request.getDob(), "yyyy-MM-dd");
        modelDto.setBirthday(date);
        modelDto.setAvatar(request.getAvatar().replace(firebasePhotoPrefix, ""));
        List<String> photos = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(request.getPhotos())) {
            request.getPhotos().forEach(p -> {
                photos.add(p.replace(firebasePhotoPrefix, ""));
            });
        }
        modelDto.setPhotos(photos);

        List<String> publicAclums = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(request.getPublicAlbum())) {
            request.getPublicAlbum().forEach(p -> {
                publicAclums.add(p.replace(firebasePhotoPrefix, ""));
            });
        }
        modelDto.setPublicAlbum(publicAclums);


        List<String> privateAclums = Lists.newArrayList();
        if (CollectionUtils.isNotEmpty(request.getPrivateAlbum())) {
            request.getPrivateAlbum().forEach(p -> {
                privateAclums.add(p.replace(firebasePhotoPrefix, ""));
            });
        }
        modelDto.setPrivateAlbum(privateAclums);
        modelDto.setCreateBy(Integer.valueOf(String.valueOf(RequestLocalInfo.getCurrentAdmin().getId())));

        String s = modelService.addNewModel(modelDto);

        return Result.ok();
    }

    @LogEvent(name = "modifyModelInfo")
    @RequestMapping(value = "/modify", method = {RequestMethod.POST})
    @ApiOperation("model资料编辑接口")
    public Result<String> modifyModel(@RequestBody ModifyModel request) {

        ModifyModelDto modelDto = new ModifyModelDto();
        BeanUtils.copyProperties(request, modelDto);
        final List<ImageDto> photos = request.getPhotos();
        if (CollectionUtils.isNotEmpty(photos)) {
            final List<ImagesDto> profilePhotos = photos.parallelStream().map(o -> ImagesDto.toDto(o.getImageCode(), o.getImageUrl())).collect(Collectors.toList());
            if (StringUtils.isNotEmpty(modelDto.getAvatar())) {
                profilePhotos.add(ImagesDto.toDto(null, modelDto.getAvatar()));
            }
            modelDto.setPhotos(profilePhotos);
        }
        final List<ImageDto> publicAlbums = request.getPublicAlbum();
        if (CollectionUtils.isNotEmpty(publicAlbums)) {
            modelDto.setPublicAlbum(publicAlbums.parallelStream().map(o -> ImagesDto.toDto(o.getImageCode(), o.getImageUrl())).collect(Collectors.toList()));
        }
        final List<ImageDto> privateAlbums = request.getPrivateAlbum();
        if (CollectionUtils.isNotEmpty(privateAlbums)) {
            modelDto.setPrivateAlbum(privateAlbums.parallelStream().map(o -> ImagesDto.toDto(o.getImageCode(), o.getImageUrl())).collect(Collectors.toList()));
        }
        Date date = DateUtil.getDate(request.getBirthday(), "yyyy-MM-dd");
        modelDto.setBirthday(date);
        modelDto.setCreateBy(Integer.valueOf(String.valueOf(RequestLocalInfo.getCurrentAdmin().getId())));

        String s = modelService.updateModel(modelDto);

        // model资料更新，需要重新注册融云平台会话
        if (StringUtils.isNotEmpty(request.getNickName())) {
            Map<String, String> header = Maps.newHashMap();
            header.put("Content-Type", "application/json");
            String avatarUrl = request.getAvatar();
            avatarUrl = userPhotoPrefix + avatarUrl.substring(avatarUrl.indexOf("/images"));
            final IMUserInfoRequest imUserInfoRequest = IMUserInfoRequest.builder().avatarUrl(avatarUrl).nickname(request.getNickName()).userCode(request.getModelUserCode()).build();
            final String result = HttpUtil.postPageBody(mebooApiUrl + "/api/auth/modifyUserInfo", header, JSONObject.toJSONString(imUserInfoRequest));
            return Result.ok(result);
        }
        return Result.ok(s);
    }


    @LogEvent(name = "removeModel")
    @RequestMapping(value = "/delete", method = {RequestMethod.POST})
    @ApiOperation("model删除接口")
    public Result<String> deleteModel(@RequestBody ModelCode modelCode) {
        final Response<UserBaseDto> response = userService.getUserBaseInfo(modelCode.getModelCode());
        if (Objects.isNull(response) || !response.isSuccess()) {
            return Result.fail("Invoke service error");
        }
        final UserBaseDto userBaseDto = response.getData();
        if (UserStatus.ACTIVE.getType() == userBaseDto.getStatus()) {
            return Result.fail("Cannot remove account which status is not disabled");
        }

        userService.removeUser(modelCode.getModelCode());
        return Result.ok("success");
    }

    @LogEvent(name = "removeImage")
    @RequestMapping(value = "/image/delete", method = {RequestMethod.POST})
    @ApiOperation("照片删除接口")
    public Result<String> deleteImage(@RequestBody ImageDto imageDto) {
        if (StringUtils.isEmpty(imageDto.getImageUrl())) {
            return Result.fail("imageUrl should not be empty!");
        }
        modelService.removeImage(imageDto.getModelUserCode(), imageDto.getImageCode(), imageDto.getImageUrl(), imageDto.getAvatarFlag());
        return Result.ok("success");
    }

    @LogEvent(name = "addImage")
    @RequestMapping(value = "/image/add", method = {RequestMethod.POST})
    @ApiOperation("照片新增接口")
    public Result<AddImageRsp> deleteImage(@RequestBody AddImageDto imageDto) {
        if (StringUtils.isEmpty(imageDto.getUrl())) {
            return Result.fail("image url should not be empty!");
        }

        String imageUrl = imageDto.getUrl();
        imageUrl = imageUrl.replace(firebasePhotoPrefix, "");


        if (StringUtils.isEmpty(imageDto.getModelUserCode())) {
            return Result.fail("modelUserCode should not be empty!");
        }
        if (imageDto.getAlbumsType() == null) {
            return Result.fail("albumsType should not be empty!");
        }

        if (isVideoFile(imageDto.getUrl()) && imageDto.getVideoLength() == null) {
            imageDto.setVideoLength(10);
        }

        final String imageCode = modelService.addImages(imageDto.getModelUserCode(), imageUrl, imageDto.getAlbumsType(), imageDto.getVideoLength(), imageDto.getAvatarFlag());
        if (StringUtils.isNotEmpty(imageCode)) {
            return Result.ok(AddImageRsp.toImage(imageCode, imageDto.getUrl()));
        }
        return Result.fail("Add image failed!");

    }



    // 判断是否为视频文件
    public static boolean isVideoFile(String fileName) {
        String[] videoExtensions = {".mp4", ".avi", ".mov", ".wmv", ".flv", ".mkv", ".mpeg", ".3gp", ".webm"};

        for (String extension : videoExtensions) {
            if (fileName.endsWith(extension)) {
                return true;
            }
        }

        return false;
    }

    @LogEvent(name = "auditModel")
    @RequestMapping(value = "/statusChange", method = {RequestMethod.POST})
    @ApiOperation("model禁、启用审核审核接口")
    public Result statusChange(@RequestBody ReviewModel reviewModel) {
        // 审核通过
        if (reviewModel.getTargetStatus() != null && reviewModel.getTargetStatus() == UserChatterMappingStatus.PASS.getType()) {
            modelService.approvalModel(reviewModel.getModelCode(), UserChatterMappingStatus.PASS.getType());
            userService.updateUserStatus(reviewModel.getModelCode(), UserStatus.ACTIVE.getType());
            return Result.ok();
        }
        // 待审核
        else if (reviewModel.getTargetStatus() != null && reviewModel.getTargetStatus() == UserChatterMappingStatus.WAITING.getType()) {
            modelService.approvalModel(reviewModel.getModelCode(), UserChatterMappingStatus.WAITING.getType());
            userService.updateUserStatus(reviewModel.getModelCode(), UserStatus.INIT.getType());
            return Result.ok();
        }
        // 审核拒绝
        else {
            modelService.approvalModel(reviewModel.getModelCode(), UserChatterMappingStatus.REJECT.getType());
            userService.updateUserStatus(reviewModel.getModelCode(), UserStatus.INIT.getType());
            return Result.ok();
        }
    }
}
